﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace Com.JunCaiSoft.Common.Verification
{
    public class IDnumber
    {
        private static string iDnumber { get; set; }
        private IDnumber(string inputIDnumber)
        {
            iDnumber = inputIDnumber;
            RegularExpression();
            IDnumberCheckResult();
        }
        /// <summary>
        /// 用该方法输入身份证前17位还可以计算出最后一位
        /// </summary>
        /// <param name="inputIDnumber"></param>
        /// <returns></returns>
        public static string CheckIDnumber(string inputIDnumber)
        {
            if (inputIDnumber.EndsWith("?", StringComparison.Ordinal))
            {
                throw new Exception("不允许输入其他字符！");
            }
            if (inputIDnumber.Length == 17)
            {
                iDnumber += "?";
            }
            var IDnumberObj = new IDnumber(inputIDnumber);
            return iDnumber;
        }
        public static bool Gender()
        {
            var genderStr = Int32.Parse(iDnumber.Substring(16, 1));
            if (genderStr % 2 == 1)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        public static int Age()
        {
            var birthDate = DateTime.Parse(iDnumber.Substring(6, 8));
            var age = DateTime.Now.Year - birthDate.Year;
            return age;
        }
        private void RegularExpression()
        {
            if (!Regex.IsMatch(iDnumber, @"(^\d{17}[X?]|\d{1}$)"))
            {
                throw new Exception("输入的身份号码有误！");
            }
        }
        private void IDnumberCheckResult()
        {
            if (iDnumber.Length != 18)
            {
                throw new Exception("输入的身份号码位数不正确！");
            }
            int sum = 0;
            for (int i = 0; i < iDnumber.Length - 1; i++)
            {
                sum += ComputeRights(Int32.Parse(iDnumber.Substring(i, 1)), i + 1);
            }
            var result = sum % 11;
            var resultChar = IDnumberResultChange(result);
            if (iDnumber.EndsWith("?", StringComparison.Ordinal))
            {
                iDnumber = iDnumber.Replace("?", resultChar);
            }
            if (iDnumber.Substring(17, 1) != resultChar)
            {
                throw new Exception("身份证号码不正确");
            }

        }
        private int ComputeRights(int input, int position)
        {
            int rights;
            switch (position)
            {
                case 1: rights = 7; break;
                case 2: rights = 9; break;
                case 3: rights = 10; break;
                case 4: rights = 5; break;
                case 5: rights = 8; break;
                case 6: rights = 4; break;
                case 7: rights = 2; break;
                case 8: rights = 1; break;
                case 9: rights = 6; break;
                case 10: rights = 3; break;
                case 11: rights = 7; break;
                case 12: rights = 9; break;
                case 13: rights = 10; break;
                case 14: rights = 5; break;
                case 15: rights = 8; break;
                case 16: rights = 4; break;
                case 17: rights = 2; break;
                default: rights = 0; break;
            }
            return input * rights;
        }
        private string IDnumberResultChange(int inputNum)
        {
            string resultChar;
            switch (inputNum)
            {
                case 1: resultChar = "0"; break;
                case 2: resultChar = "X"; break;
                case 3: resultChar = "9"; break;
                case 4: resultChar = "8"; break;
                case 5: resultChar = "7"; break;
                case 6: resultChar = "6"; break;
                case 7: resultChar = "5"; break;
                case 8: resultChar = "4"; break;
                case 9: resultChar = "3"; break;
                case 10: resultChar = "2"; break;
                default: resultChar = "1"; break;
            }
            return resultChar;
        }
    }
}
